package com.fw.application.controller;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fw.application.controller.base.BaseController;
import com.fw.application.controller.v2.shop.read.V2ReadPackageController;
import com.fw.common.AliComm;
import com.fw.common.Builder;
import com.fw.common.IdXD;
import com.fw.constant.Constant;
import com.fw.enums.LogsModelEnum;
import com.fw.enums.LogsTypeEnum;
import com.fw.exception.CustomException;
import com.fw.mes.Result;
import com.fw.system.web.model.entity.*;
import com.fw.system.web.model.form.WithdrawForm;
import com.fw.system.web.model.vo.LogsVo;
import com.fw.system.web.model.vo.MoneysVo;
import com.fw.system.web.model.vo.WithdrawVo;
import com.fw.system.web.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.fw.mes.ResultUtils.success;

/**
 * <p>
 * 用户钱包表 前端控制器
 * </p>
 *
 * @author
 * @since 2021-05-10
 */
@RestController
@RequestMapping("/moneys")
@Api(tags = "钱包相关")
@RequiredArgsConstructor
public class FwMoneysController implements BaseController {

    private final IFwUserService userService;
    private final IFwLogsService logsService;
    private final IFwMoneysService moneysService;
    private final IFwShangjiaService shangjiaService;
    private final IFwRuleDatasService ruleDatasService;
    private final IdXD idXD;
    private final AliComm aliComm;
    private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
    private final IFwWithdrawShangjiaService fwWithdrawShangjiaService;
    private final IFwWithdrawService fwWithdrawService;
    private final IFwShangjipoolService fwShangjipoolService;
    private final IFwShangjiaDeleteLogService deleteLogService;
    private final V2ReadPackageController readPackageController;
    private final IFwReadPackageLogService readPackageLogService;
    private final IFwReadPackageService readPackageService;
    private final IFwReadPackageTaskContentService taskContentService;
    private final IFwCurrencyLogService currencyLogService;


    /**
     * shlo:查询我的钱包数据(消证,商甲,积分余额)
     *
     * @return
     */
    @GetMapping("/findMyMoney")
    @ApiOperation("shlo:查询我的钱包数据(消证,商甲,积分余额)")
    public Result<MoneysVo> findMyMoney() {
        FwUser user = getUser();
        FwMoneys moneys = moneysService.getOne(Wrappers.<FwMoneys>lambdaQuery().eq(FwMoneys::getUserId, user.getId()));
        MoneysVo moneysVo = new MoneysVo();
        BeanUtil.copyProperties(moneys, moneysVo);
        return success(moneysVo);
    }

    /**
     * shlo:查询我的消证-明细
     *
     * @return
     */
    @GetMapping("/findMyDisappearList")
    @ApiOperation("shlo:查询我的消证-明细")
    public Result<List<LogsVo>> findMyDisappearList() {
        FwUser user = getUser();
        List<FwLogs> logs = logsService.list(Wrappers.<FwLogs>lambdaQuery()
                .eq(FwLogs::getModelName, LogsModelEnum.DISAPPEAR_MODEL.getModelName())
                .eq(FwLogs::getBuiId, user.getId()).orderByDesc(FwLogs::getCreateTime));
        ArrayList<LogsVo> logsVos = new ArrayList<>();
        for (FwLogs log : logs) {
            LogsVo logsVo = new LogsVo();
            BeanUtil.copyProperties(log, logsVo);
            logsVos.add(logsVo);
        }

        return success(logsVos);
    }

    /**
     * shlo:查询我的消证-兑换积分
     *
     * @return
     */
    @GetMapping("/findMyDisappearIntegral")
    @ApiOperation("shlo:查询我的消证-兑换积分")
    public Result<List<LogsVo>> findMyDisappearIntegral() {
        FwUser user = getUser();
        List<FwLogs> logs = logsService.list(Wrappers.<FwLogs>lambdaQuery()
                .eq(FwLogs::getIsType, LogsTypeEnum.MONEY_CONSUMPTION.getTypeName())
                .eq(FwLogs::getModelName, LogsModelEnum.DISAPPEAR_MODEL.getModelName())
                .eq(FwLogs::getBuiId, user.getId()).orderByDesc(FwLogs::getCreateTime));
        ArrayList<LogsVo> logsVos = new ArrayList<>();
        for (FwLogs log : logs) {
            LogsVo logsVo = new LogsVo();
            BeanUtil.copyProperties(log, logsVo);
            logsVos.add(logsVo);
        }

        return success(logsVos);
    }

    /**
     * shlo:查询我的消证-兑换积分 todo 此处查询条件为查询积分支出,后续消证兑换商甲逻辑完善后需改动
     *
     * @return
     */
    /*@GetMapping("/findMyShangJia")
    @ApiOperation("shlo:查询我的消证-兑换商甲")
    public Result<List<LogsVo>> findMyDisappearShangJia() {
        FwUser user = getUser();
        List<FwLogs> logs = logsService.list(Wrappers.<FwLogs>lambdaQuery()
                .eq(FwLogs::getIsType, LogsTypeEnum.MONEY_CONSUMPTION.getTypeName())
                .eq(FwLogs::getModelName, LogsModelEnum.DISAPPEAR_MODEL.getModelName())
                .eq(FwLogs::getBuiId, user.getId()));
        ArrayList<LogsVo> logsVos = new ArrayList<>();
        for (FwLogs log : logs) {
            LogsVo logsVo = new LogsVo();
            BeanUtil.copyProperties(log,logsVo);
            logsVos.add(logsVo);
        }

        return success(logsVos);
    }*/

    /**
     * shlo:查询我的积分-明细
     *
     * @return
     */
    @GetMapping("/findMyIntegralList")
    @ApiOperation("shlo:查询我的积分-明细/查询提现的{查询所有类型的积分明细}")
    public Result<List<LogsVo>> findMyIntegralList() {
        FwUser user = getUser();
        List<LogsVo> voList = logsService.list(Wrappers.<FwLogs>lambdaQuery()
                .eq(FwLogs::getModelName, LogsModelEnum.INTEGRAL_MODEL.getModelName())
                .eq(FwLogs::getBuiId, user.getId()).orderByDesc(FwLogs::getCreateTime)).parallelStream().map(item -> {
            LogsVo vo = Builder.of(LogsVo::new).build();
            BeanUtil.copyProperties(item, vo);
            return vo;
        }).collect(Collectors.toList());
        return success(voList);
    }

    /**
     * shlo:查询我的积分-兑换
     *
     * @return
     */
    @GetMapping("/findMyIntegralFreed")
    @ApiOperation("shlo:查询我的积分-兑换")
    public Result<List<LogsVo>> findMyIntegralFreed() {
        FwUser user = getUser();
        List<FwLogs> logs = logsService.list(Wrappers.<FwLogs>lambdaQuery()
                .eq(FwLogs::getIsType, LogsTypeEnum.INTEGRAL_RELEASE.getTypeName())
                .eq(FwLogs::getModelName, LogsModelEnum.INTEGRAL_MODEL.getModelName())
                .eq(FwLogs::getBuiId, user.getId()).orderByDesc(FwLogs::getCreateTime));
        ArrayList<LogsVo> logsVos = new ArrayList<>();
        for (FwLogs log : logs) {
            LogsVo logsVo = new LogsVo();
            BeanUtil.copyProperties(log, logsVo);
            logsVos.add(logsVo);
        }

        return success(logsVos);
    }

    /**
     * shlo:查询我的积分-加速
     *
     * @return
     */
    @GetMapping("/findMyIntegralGet")
    @ApiOperation("shlo:查询我的积分-加速")
    public Result<List<LogsVo>> findMyIntegralGet() {
        FwUser user = getUser();
        List<FwLogs> logs = logsService.list(Wrappers.<FwLogs>lambdaQuery()
                .eq(FwLogs::getIsType, LogsTypeEnum.INTEGRAL_SPEED.getTypeName())
                .eq(FwLogs::getModelName, LogsModelEnum.INTEGRAL_MODEL.getModelName())
                .eq(FwLogs::getBuiId, user.getId()).orderByDesc(FwLogs::getCreateTime));
        ArrayList<LogsVo> logsVos = new ArrayList<>();
        for (FwLogs log : logs) {
            LogsVo logsVo = new LogsVo();
            BeanUtil.copyProperties(log, logsVo);
            logsVos.add(logsVo);
        }

        return success(logsVos);
    }

    /**
     * 积分提现
     *
     * @return
     */
    @GetMapping("/withdrawIntegralStay")
    @ApiOperation("shlo:积分提现-待输入")
    public Result<WithdrawVo> withdrawIntegralStay() {

        //获取用户数据
        FwUser user = getUser();
        FwMoneys moneys = moneysService.getOne(Wrappers.<FwMoneys>lambdaQuery().eq(FwMoneys::getUserId, user.getId()));
        //获取积分提现手续费比例
        FwRuleDatas data = ruleDatasService.getOne(Wrappers.<FwRuleDatas>lambdaQuery().eq(FwRuleDatas::getId, Constant.IsRuleData.WITHDRAW_INTEGRAL_ID));
        //送回vo
        WithdrawVo withdrawVo = new WithdrawVo();
        withdrawVo.setIntegral(moneys.getIntegral());
        withdrawVo.setPoundage(data.getRuleCount());

        return success(withdrawVo);
    }


    @Autowired
    private IFwReadPackageTaskService readPackageTaskService;

    /**
     * 积分提现
     *
     * @return
     */
    @PostMapping("/withdrawIntegral")
    @ApiOperation("shlo:积分提现-已输入")
    @Transactional(rollbackFor = Exception.class)
    public synchronized Result withdrawIntegral(@RequestBody WithdrawForm withdrawForm) {
        //获取当前登陆者信息
        FwUser fwUser = getUser();
        FwRuleDatas datas = ruleDatasService.getById("44");

       /* if (withdrawForm.getMoney().compareTo(new BigDecimal("1000")) > 0)
            return new Result().fail(0, "单次输入不能超过1000");*/


        //校验支付密码
        FwUser user = userService.getOne(Wrappers.<FwUser>lambdaQuery().eq(FwUser::getId, fwUser.getId()));

        if (withdrawForm.getPayPassWord() == null) {
            return new Result().fail(115, "请输入支付密码");
        }
        if (!user.getPayPassWord().equals(withdrawForm.getPayPassWord())) {
            return new Result().fail(105, "支付密码错误,请核实");
        }
        if (datas != null && StringUtils.isNotBlank(datas.getRuleName())) {
            LocalTime startTime = LocalTime.parse(datas.getRuleName().substring(0, datas.getRuleName().indexOf("-")));
            LocalTime endTime = LocalTime.parse(datas.getRuleName().substring(datas.getRuleName().indexOf("-") + 1, datas.getRuleName().length()));
            if (LocalTime.now().compareTo(startTime) < 0 || LocalTime.now().compareTo(endTime) > 0)
                return new Result<WithdrawVo>().fail(0, "未到提现时间");
        }

        FwMoneys moneys = moneysService.getOne(Wrappers.<FwMoneys>lambdaQuery().eq(FwMoneys::getUserId, fwUser.getId()));
        if (withdrawForm.getMoney().compareTo(new BigDecimal(withdrawForm.getMoney().intValue())) > 0 || withdrawForm.getMoney().compareTo(new BigDecimal(0)) < 1 || withdrawForm.getMoney().compareTo(moneys.getIntegral()) > 0) {
            return new Result().fail(1, "请输入正确金额");
        }
        if (withdrawForm.getMoney().compareTo(moneys.getIntegral()) > 0) {
            return new Result().fail(1, "请输入正确金额");
        }
        //增加提现标识、
        FwCurrencyLog currencyLog = currencyLogService.getOne(Wrappers.<FwCurrencyLog>lambdaQuery().eq(FwCurrencyLog::getUserId, fwUser.getId()).eq(FwCurrencyLog::getLogType, 8)
                .last("AND TO_DAYS(create_time) = TO_DAYS(NOW())"));
        if (currencyLog !=null){
            return new Result().fail(0,"提现每日只有一次机会，不限金额");
        }else{

            Builder.of(FwCurrencyLog::new).with(FwCurrencyLog::setId, idXD.nextId()).
                    with(FwCurrencyLog::setCreateTime, LocalDateTime.now()).
                    with(FwCurrencyLog::setLogCount, withdrawForm.getMoney()).
                    with(FwCurrencyLog::setInfoFrom, 2).with(FwCurrencyLog::setLogName, "提现标识").
                    with(FwCurrencyLog::setUserId, fwUser.getId()).with(FwCurrencyLog::setLogType, 8).build().insert();
        }
        moneys.setIntegral(moneys.getIntegral().subtract(withdrawForm.getMoney()));
        moneys.setUpdateTime(LocalDateTime.now());
        moneys.setUpdateBy(getUser().getId());
        moneysService.updateById(moneys);
        //红包活动
        final FwReadPackage readPackage = readPackageService.getOne(Wrappers.<FwReadPackage>lambdaQuery().eq(FwReadPackage::getIsState, 1));
        if (readPackage != null) {
            final FwReadPackageLog log = readPackageLogService.getOne(Wrappers.<FwReadPackageLog>lambdaQuery().
                    eq(FwReadPackageLog::getReadId, readPackage.getId())
                    .eq(FwReadPackageLog::getUserId, this.getUser().getId()));
            if (log != null) {
                final FwReadPackageTaskContent content = taskContentService.getOne(Wrappers.<FwReadPackageTaskContent>lambdaQuery().eq(FwReadPackageTaskContent::getTaskId, 4)
                        .eq(FwReadPackageTaskContent::getUserId, this.getUser().getId()));
                if (content == null) {
                    String userId = this.getUser().getId();
                    FwReadPackageTask packageTask = readPackageTaskService.getById("4");
                    if (packageTask == null) {
                        return new Result().fail(0, "该任务不存在");
                    }
                    Builder.of(FwReadPackageTaskContent::new)
                            .with(FwReadPackageTaskContent::setId, idXD.nextId())
                            .with(FwReadPackageTaskContent::setCreateTime, LocalDateTime.now())
                            .with(FwReadPackageTaskContent::setUserId, userId)
                            .with(FwReadPackageTaskContent::setReadId, packageTask.getReadId())
                            .with(FwReadPackageTaskContent::setUserNum, 1)
                            .with(FwReadPackageTaskContent::setTaskId, packageTask.getId())
                            .with(FwReadPackageTaskContent::setTaskAmount, packageTask.getTaskAmount()).build().insert();
                    //给红包累加额度
                    FwReadPackageLog packageLog = readPackageLogService.getOne(Wrappers.<FwReadPackageLog>lambdaQuery().eq(FwReadPackageLog::getUserId, userId).eq(FwReadPackageLog::getReadId, packageTask.getReadId()));
                    readPackageLogService.updateById(packageLog.setStartNum(packageLog.getStartNum().add(packageTask.getTaskAmount())));
                }
            }

        }


        //获取积分提现手续费比例
        FwRuleDatas data = ruleDatasService.getOne(Wrappers.<FwRuleDatas>lambdaQuery().eq(FwRuleDatas::getId, Constant.IsRuleData.WITHDRAW_INTEGRAL_ID));
        //获取扣除手续费后的实际提现金额
        BigDecimal money = withdrawForm.getMoney();//输入的金额
        //扣除提现的积分

        BigDecimal ruleCount = data.getRuleCount().multiply(new BigDecimal("0.01"));//手续费比例
        BigDecimal poundage = money.multiply(ruleCount);//需要扣除的手续费
        poundage = poundage.setScale(2, BigDecimal.ROUND_UP);//保留两位小数
        BigDecimal withdrawMoney = money.subtract(poundage);//实际提现的金额
        withdrawMoney = withdrawMoney.setScale(2, BigDecimal.ROUND_UP);//保留两位小数
        //调支付
        try {
            aliComm.aliTransfer(withdrawForm.getAliPhone(),//提现到的支付宝账号
                    withdrawMoney,//支付金额,
                    withdrawForm.getAliUserName()
            );
            //======
            //累计提现任务
            readPackageController.taskCommit("4", this.getUser().getId());
            FwWithdraw fwWithdraw = new FwWithdraw();
            fwWithdraw.setId(idXD.nextId());
            fwWithdraw.setUserId(user.getId());
            fwWithdraw.setStatus(1);
            fwWithdraw.setCreateBy(user.getId());
            fwWithdraw.setCreateTime(LocalDateTime.now());
            fwWithdraw.setUpdateBy(user.getId());
            fwWithdraw.setUpdateTime(LocalDateTime.now());
            fwWithdraw.setIntegral(money);
            fwWithdraw.setMoney(withdrawMoney);
            fwWithdraw.setRemark("扣除手续费" + poundage.toString());
            fwWithdrawService.save(fwWithdraw);
            //增加销毁标识日志和销毁明细
            FwShangjia consumer = shangjiaService.getOne(Wrappers.<FwShangjia>lambdaQuery().eq(FwShangjia::getId, Constant.ShangJia.CONSUME_ID));
            BigDecimal presentPrice = consumer.getPresentPrice();
            deleteLogService.saveLabLog(withdrawForm.getMoney(), fwUser.getId());

            logsService.saveLogs(user.getId(), user.getId(), LogsTypeEnum.INTEGRAL_WITHDRAWAL.getTypeName(), LogsModelEnum.INTEGRAL_MODEL.getModelName(), "积分提现" + withdrawMoney + "元,手续费" + poundage + "元", withdrawForm.getMoney().toString());
        } catch (IllegalArgumentException e) {
            //AlipayFundTransToaccountTransferResponse
            JSONObject jsonObject = JSON.parseObject(e.getMessage());
            String msg = jsonObject.getJSONObject("alipay_fund_trans_toaccount_transfer_response").getString("sub_msg");
            throw new CustomException(msg,1001);
        } catch (AlipayApiException e) {
            throw new CustomException(e.getMessage(),1001);
        }
        return success();
    }


    /**
     * 获取剩余额度比例最多的商甲仓库
     * <p>
     * 用来决定是那个 需要销毁那个仓的商甲
     *
     * @return
     */
    public FwShangjia getCountMax() {
        List<FwShangjia> list = shangjiaService.list();
        for (int i = 0; i < list.size(); i++) {
            for (int j = i; j < list.size(); j++) {
                if (list.get(i).getShangjiaQuota().divide(list.get(i).getShopIssue(), 2, BigDecimal.ROUND_UP)
                        .compareTo(list.get(j).getShangjiaQuota().divide(list.get(j).getShopIssue(), 2, BigDecimal.ROUND_UP)) > 0) {
                    FwShangjia newSj = list.get(i);
                    list.set(i, list.get(j));
                    list.set(j, newSj);
                }
            }
        }
        return list.get(0);
    }

    public static void main(String[] args) {
        BigDecimal b1 = new BigDecimal("10000");
        BigDecimal b2 = new BigDecimal("68000");
        BigDecimal divide = b2.divide(b1, 2, BigDecimal.ROUND_UP);
        System.out.println(divide.toString().concat("万"));

    }


}

